﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Viettel.VOFFICE.DAO.Enums;

namespace Viettel.VOFFICE.DAO.Helpers
{
    public class EnumHelper<T> where T : struct
    {
        /// <summary>
        /// Convert gía trị string thành enum
        /// </summary>
        /// <param name="strEnumValue"></param>
        /// <returns></returns>
        public static T? ToEnum(string strEnumValue)
        {
            if (Enum.IsDefined(typeof(T), strEnumValue))
            {
                var c = (T)Enum.Parse(typeof(T), strEnumValue, true);
                return c;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// Lấy ra Dictionary(key = gía trị enum, value = string-attribute của enum đó)
        /// </summary>
        /// <returns></returns>
        public static Dictionary<object, string> GetDicValues()
        {
            var enumType = typeof(T);
            var underlyingType = Enum.GetUnderlyingType(enumType);
            var values = new Dictionary<object, string>();

            foreach (var fi in enumType.GetFields())
            {
                var attrs = fi.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
                if (attrs != null && attrs.Length > 0)
                    values.Add(Convert.ChangeType(Enum.Parse(enumType, fi.Name), underlyingType),
                        //ưu tiên key lấy từ resource trước
                        Resources.Resources.ResourceManager.GetString(attrs[0].Value) ?? attrs[0].Value);

            }
            return values;
        }

        /// <summary>
        /// lấy ra string attribute từ giá trị enum truyền vào
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GetStringValue(Enum value)
        {
            if (null == value) return string.Empty;
            var str = StringEnum.GetStringValue(value);
            return Resources.Resources.ResourceManager.GetString(str) ?? str;
        }

        /// <summary>
        /// Lấy toàn bộ giá trị của enum để đưa vào 1 list
        /// </summary>
        /// <returns></returns>
        public static List<T> GetValues()
        {
            System.Diagnostics.Debug.Assert(typeof(T).IsEnum);
            var fields = typeof(T).GetFields(BindingFlags.Static | BindingFlags.Public);
            return fields.Select(t => (T)t.GetValue(null)).ToList();
        }

        /// <summary>
        /// lấy ra giá trị enum từ tên
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T GetByValue(string value)
        {
            var field = GetValues();
            return field.FirstOrDefault(o => o.ToString().ToUpper() == value.ToUpper());
        }

        /// <summary>
        /// lấy ra giá trị enum từ vị trí của nó
        /// </summary>
        /// <param name="position"></param>
        /// <returns></returns>
        public static T GetByPosition(int position)
        {
            var field = GetValues();
            T t = field.FirstOrDefault(o => field.IndexOf(o) == position);
            return t;
        }
    }
}
